package com.zjb.openfirecli.services;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.chat2.Chat;
import org.jivesoftware.smack.chat2.ChatManager;
import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.iqregister.AccountManager;
import org.jivesoftware.smackx.muc.MucEnterConfiguration;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.muc.MultiUserChatManager;
import org.jivesoftware.smackx.xdata.Form;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Localpart;
import org.jxmpp.jid.parts.Resourcepart;

import java.util.ArrayList;
import java.util.List;

public class OpenfireCliServices {
    /**
     * 服务器名称
     */
    private String HOST_NAME = "localhost";
    /**
     * openfire 服务器地址
     */
    private String HOST_ADDRESS = "127.0.0.1";
    /**
     * 端口地址
     */
    private Integer HOST_PORT = 5222;


    public OpenfireCliServices() {
    }

    public OpenfireCliServices(String HOST_NAME, String HOST_ADDRESS, Integer HOST_PORT) {
        this.HOST_NAME = HOST_NAME;
        this.HOST_ADDRESS = HOST_ADDRESS;
        this.HOST_PORT = HOST_PORT;
        init();
    }

    /**
     * xmpp连接配置
     */
    private XMPPTCPConnectionConfiguration connectConfig;
    /**
     * xmpp连接
     */
    private XMPPTCPConnection connection;
    /**
     * 一对一聊天管理器
     */
    private ChatManager chatManager;
    /**
     * 聊天室管理器
     */
    private MultiUserChatManager multiUserChatManager;

    /**
     * 初始化连接
     */
    private void init() {
        try {
            connectConfig = XMPPTCPConnectionConfiguration.builder()
                    .setXmppDomain(HOST_NAME)
                    .setHost(HOST_ADDRESS)
                    .setPort(HOST_PORT)
                    .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
                    .setSendPresence(true)
                    .build();
            connection = new XMPPTCPConnection(connectConfig);
            connection.connect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 注册用户
     *
     * @param userName
     * @param password
     */
    public void createUser(String userName, String password) {
        try {
            AccountManager accountManager = AccountManager.getInstance(connection);
            // 允许使用不安全连接，创建用户
            accountManager.sensitiveOperationOverInsecureConnection(true);
            accountManager.createAccount(Localpart.from(userName), password);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 登陆
     *
     * @param username
     * @param password
     */
    public void login(String username, String password) {
        try {
            connection.login(username, password);
            multiUserChatManager = MultiUserChatManager.getInstanceFor(connection);
            chatManager = ChatManager.getInstanceFor(connection);
            chatManager.addIncomingListener(new IncomingChatMessageListener() {
                @Override
                public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
                    System.out.println("message from : " + from + " : " + message.getBody());
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送消息
     *
     * @param toUserName
     * @param msgContext
     */
    public void sendMessage(String toUserName, String msgContext) {
        try {
            Chat chat = chatManager.chatWith(JidCreate.entityBareFrom(String.format("%s@%s", toUserName, HOST_NAME)));
            Message message = new Message();
            message.setType(Message.Type.chat);
            message.setBody(msgContext);
            chat.send(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建群聊
     *
     * @param room
     * @return
     * @throws Exception
     */
    public void createChatRoom(String room, String owner, Integer memberNum) {
        try {
            //组装群聊jid,这里需要注意一下,群jid的格式就是  群名称@conference.openfire服务器名称
            String jid = room + "@conference." + HOST_NAME;
            EntityBareJid roomJid = JidCreate.entityBareFrom(jid);
            MultiUserChat muc = multiUserChatManager.getMultiUserChat(roomJid);
            muc.create(Resourcepart.from(room));
            // 获得聊天室的配置表单
            Form form = muc.getConfigurationForm();
            // 根据原始表单创建一个要提交的新表单。
            Form submitForm = form.createAnswerForm();
            //设置房间最大用户数
            List<String> maxusers = new ArrayList<>();
            maxusers.add(memberNum + "");
            submitForm.setAnswer("muc#roomconfig_maxusers", maxusers);
            // 设置聊天室的新拥有者
            List<String> owners = new ArrayList<>();
            owners.add(owner + "@" + HOST_NAME);
            submitForm.setAnswer("muc#roomconfig_roomowners", owners);
            //设置为公共房间
            submitForm.setAnswer("muc#roomconfig_publicroom", true);
            // 设置聊天室是持久聊天室，即将要被保存下来
            submitForm.setAnswer("muc#roomconfig_persistentroom", true);
            // 房间仅对成员开放
            submitForm.setAnswer("muc#roomconfig_membersonly", false);
            // 允许占有者邀请其他人
            submitForm.setAnswer("muc#roomconfig_allowinvites", true);
            // 进入不需要密码
            submitForm.setAnswer("muc#roomconfig_passwordprotectedroom", false);
            // 登录房间对话
            submitForm.setAnswer("muc#roomconfig_enablelogging", true);
            // 仅允许注册的昵称登录
            submitForm.setAnswer("x-muc#roomconfig_reservednick", false);
            // 允许使用者修改昵称
            submitForm.setAnswer("x-muc#roomconfig_canchangenick", true);
            // 允许用户注册房间
            submitForm.setAnswer("x-muc#roomconfig_registration", false);
            // 发送已完成的表单（有默认值）到服务器来配置聊天室
            muc.sendConfigurationForm(submitForm);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 加入群聊会议室
     *
     * @param room
     * @param userName
     * @param historyMsgNum
     */
    public void joinChatRoom(String room, String userName, Integer historyMsgNum) {
        try {
            //群jid
            String jid = room + "@conference." + HOST_NAME;
            //jid实体创建
            EntityBareJid groupJid = JidCreate.entityBareFrom(jid);
            //通过群管理对象获取该群房间对象
            MultiUserChat multiUserChat = multiUserChatManager.getMultiUserChat(groupJid);
            MucEnterConfiguration.Builder builder = multiUserChat.getEnterConfigurationBuilder(Resourcepart.from(userName));
            //只获取最后99条历史记录
            builder.requestMaxCharsHistory(historyMsgNum);
            MucEnterConfiguration mucEnterConfiguration = builder.build();
            //加入群
            multiUserChat.join(mucEnterConfiguration);
            multiUserChat.addMessageListener(new MessageListener() {
                @Override
                public void processMessage(Message message) {
                    System.out.println("收到房间消息：" + message.getBody());
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送群聊普通消息
     *
     * @param room
     * @param msgContext
     */
    public void sendChatRoomMessage(String room, String msgContext) {
        try {
            //拼凑jid
            String jid = room + "@conference." + HOST_NAME;
            //创建jid实体
            EntityBareJid groupJid = JidCreate.entityBareFrom(jid);
            //群管理对象
            MultiUserChat multiUserChat = multiUserChatManager.getMultiUserChat(groupJid);
            //发送信息
            Message message = new Message();
            message.setType(Message.Type.groupchat);
            message.setBody(msgContext);
            multiUserChat.sendMessage(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 退出群聊
     *
     * @param room
     */
    public void quitRoom(String room) {
        try {
            String jid = room + "@conference." + HOST_NAME;
            EntityBareJid groupJid = JidCreate.entityBareFrom(jid);
            MultiUserChat multiUserChat = multiUserChatManager.getMultiUserChat(groupJid);
            //退出群
            multiUserChat.leave();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
